package com.geekydoo;

import java.io.IOException;
import java.util.NoSuchElementException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

/**
 * The purpose of this class is to start the program, set up logging, and begin
 * the main command loop which prompts for user commands.
 * 
 * @author Patrick Dutch
 */
public class GeekyDooMain {

	private static Logger logger = Logger.getLogger("geekydoo");

	// The messages displayed to the user at program startup and termination
	private static final String MSG_WELCOME = "Welcome to GeekyDoo! You can begin typing commands now.\n";
	private static final String MSG_GOODBYE = "\nThanks for using GeekyDoo. Goodbye!";

	// The command-line prompt displayed by this program
	private static final String PROMPT = ">> ";

	// Error messages that could be printed by this class
	private static final String ERROR_STARTUP = "Error encountered during program startup!";

	/**
	 * The main method gets the ActionHandler which will be used by this
	 * execution of the program, prints a welcome message, and begins a while
	 * loop that will run and prompt for the next command until an exit command
	 * is executed, the user presses control-c, or a GeekyDooException is
	 * caught.
	 * 
	 * @param args String array of arguments passed to the program
	 */
	public static void main(String[] args) {
		try {
			setUpLogging();

			ActionHandler actionHandler = ActionHandler.getActionHandler();

			InputOutputHandler.printToConsole(MSG_WELCOME, false, false);

			String line;
			while (true) {
				line = InputOutputHandler.getInputFromConsole(PROMPT, false);
				actionHandler.execute(line);
			}
		}
		catch (NoSuchElementException e) {
			InputOutputHandler.printToConsole(MSG_GOODBYE, false, false);
			logger.info("User pressed ctrl-c from the console, exiting the program.");
		}
		catch (GeekyDooException e) {
			logger.log(Level.SEVERE, "Program terminating with error: " + e.getMessage(), e.getParentException());
			InputOutputHandler.printToConsole(e.getMessage(), false, false);
		}
	}

	/**
	 * This method configures the logger that will be used.
	 * 
	 * @throws GeekyDooException If an error occurs while setting up the logger
	 */
	private static void setUpLogging() throws GeekyDooException {
		FileHandler errorLogHandler;
		FileHandler infoLogHandler;

		try {
			logger.setUseParentHandlers(false);

			// This handler directs output at severity level "warning" and
			// higher to one file
			errorLogHandler = new FileHandler("geekydooError.log", false);
			errorLogHandler.setLevel(Level.WARNING);

			// This handler directs output at severity level "info" and higher
			// to a different file than the one above
			infoLogHandler = new FileHandler("geekydooInfo.log", false);
			infoLogHandler.setLevel(Level.INFO);

			logger.addHandler(errorLogHandler);
			logger.addHandler(infoLogHandler);

			SimpleFormatter formatter = new SimpleFormatter();
			errorLogHandler.setFormatter(formatter);
			infoLogHandler.setFormatter(formatter);
		}
		catch (SecurityException e) {
			GeekyDooException gde = new GeekyDooException(ERROR_STARTUP, e);
			throw gde;
		}
		catch (IOException e) {
			GeekyDooException gde = new GeekyDooException(ERROR_STARTUP, e);
			throw gde;
		}
	}
}
